//Plays complete random games of dominion.c
//

#include <stdio.h>
#include <stdlib.h>

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <assert.h>
#include<time.h>

 FILE * fd; //output file for results
 int failCount = 0;


//FunctionFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//picks random set of cards
int pickCards(int *deck, int deckSize){
	int kingCard[] = {adventurer, council_room, feast, gardens, mine, remodel,
		smithy, village, baron, great_hall, minion, steward, tribute, ambassador,
		cutpurse, embargo, outpost, salvager, sea_hag, treasure_map};
	int kingCardSize = sizeof(kingCard)/sizeof(kingCard[0]);
	int random;
	int i, j;
	
	//chose random card set
	for(i=0; i<deckSize; i++){
		random = rand()%kingCardSize; //random card from set
		deck[i] =kingCard[random]; // place card in deck
		
		//remove picked card to prevent repeats
		for(j=random;j<kingCardSize;j++){
			kingCard[j] = kingCard[j+1];		
		}
		kingCardSize--; //reset deck size
	}
	return 0;
} 
//FunctionFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//returns the character string of the card name for printing results
char* cardName(int cardNumber){
	switch( cardNumber ) 
    {
    case curse:
      return "curse";
    case estate:
      return "estate";
    case duchy:
      return "duchy";
    case province:
      return "province";
    case copper:
      return "copper";
    case silver:
      return "silver";
    case gold:
      return "gold";
    case adventurer:
      return "adventurer";
    case council_room:
      return "council_room";
    case feast:
      return "feast";
    case gardens:
      return "gardens";
    case mine:
      return "mine";
    case remodel:
      return "remodel";
    case smithy:
      return "smithy";
    case village:
      return "village";
    case baron:
      return "baron";
    case great_hall:
      return "great_hall";
    case minion:
      return "minion";
    case steward:
      return "steward";
    case tribute:
      return "tribute";
    case ambassador:
      return "ambassador";
    case cutpurse:
      return "cutpurse";
    case embargo: 
      return "embargo";
    case outpost:
      return "outpost";
    case salvager:
      return "salvager";
    case sea_hag:
      return "sea_hag";
    case treasure_map:
      return "treasure_map";
    }
	
  return NULL;
}
//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//set choice values to appropriate state for card
int setChoice(int* choice1, int *choice2, int* choice3, int card, struct gameState* game, int player){
	int number;
	int repeat = 1;
	int i;
	
	switch( card ) 
    {
		//set card to be gained
		case feast:
			while(repeat == 1){
				number = rand() % treasure_map;
				if(game->supplyCount[number] > 0 && getCost(number) < 5 ){
					repeat = 0;
					*choice1 = number;
					printf("\t\t^^^^^Choice1: %s  || supplyCount: %i\n", cardName(*choice1), game->supplyCount[number] );
				}
			}
			return 0;
		//set card to trash and gain
		case mine: 
			for (i = 0; i < numHandCards(game); i++) {
			  if (handCard(i, game) >= copper && handCard(i,game) <= gold){
				*choice1 = i;
				if(*choice1 != gold){
					*choice2 = handCard(*choice1, game) +1;					
				}
				else{
					*choice2 = handCard(*choice1, game);
					
				}
				printf("\t\t^^^^^Choice1 (trash): %s\n", cardName(handCard(*choice1, game)) );
				printf("\t\t^^^^^Choice2 (gain): %s\n", cardName(*choice2) );
				return 0;
			  }//end if		
			}
			return 0;
		case remodel:
			*choice1 = rand() % game->handCount[player];
			printf("\t\t^^^^^Choice1 (trash): %s  || cost: %i\n", cardName(handCard(*choice1, game)), getCost(handCard(*choice1, game)) );
			while(repeat == 1){
				number = rand() % treasure_map;
				if(game->supplyCount[number] > 0 && getCost(number) <= getCost(*choice1) + 2 ){
					repeat = 0;
					*choice2 = number;
					printf("\t\t^^^^^Choice2 (gain): %s  || cost: %i\n", cardName(*choice2), getCost(*choice2) );
				}
			}			
			return 0;
		case baron:
			for (i = 0; i < numHandCards(game); i++) {
			  if (handCard(i, game) == estate){
				*choice1 = 1;
				printf("\t\t^^^^^Choice1: TRUE\n" );
				return 0;
			  }			  
			}
			*choice1 = 0;
			printf("\t\t^^^^^Choice1: False\n");
			return 0;			
		case minion:
			if(rand()%2){
				*choice1 = 1;
				printf("\t\t^^^^^Choice1: 1 = +2 coins\n");
			}
			else{
				*choice1 = 2;
				printf("\t\t^^^^^Choice1: 2 = redraw\n");
			}
			return 0;
		case steward:
			*choice1 = rand() % 3 + 1;
			printf("\t\t^^^^^Choice1: %i\n", *choice1 );
			if(*choice1 == 3){
				*choice2 = rand() % game->handCount[player];
				*choice3 = rand() % game->handCount[player]-1;
				printf("\t\t^^^^^Choice2 (trash): %s\n", cardName(handCard(*choice2, game)) );
				printf("\t\t^^^^^Choice3 (trash): %s\n", cardName(handCard(*choice3, game)) );
			}			
			return 0;		
		case ambassador:
			*choice1 = rand() % game->handCount[player];
			*choice2 = 1;
			printf("\t\t^^^^^Choice1 (trash): %s\n", cardName(handCard(*choice1, game)) );
			printf("\t\t^^^^^Choice2 (amount): %i\n", *choice2 );
			return 0;		
		case embargo:
			while(repeat == 1){
				number = rand() % treasure_map;
				if(game->supplyCount[number] > 0){
					repeat = 0;
					*choice1 = number;
					printf("\t\t^^^^^Choice1 : %s\n", cardName(*choice1) );
				}
			}
			return 0;		
		case salvager:
			*choice1 = rand() % game->handCount[player];
			printf("\t\t^^^^^Choice1 (trash): %s \n", cardName(handCard(*choice1, game)) );
			return 0;		
    }//end switch

	return 0;
}
//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//plays cards while player has actions availble
int actionPhase(struct gameState* game){

	int i;
	int actionCards = 0;
	int cards[MAX_DECK];
	int handPos;
	int actions = game->numActions;
	int choice1 = 0, choice2 = 0, choice3 = 0;
	int player = whoseTurn(game);

	while(actions > 0){
		choice1 = 0;
		choice2 = 0;
		choice3 = 0;
		actionCards = 0;
		//mark hand positions of action cards
		for (i = 0; i < numHandCards(game); i++) {
		  if (handCard(i, game) >= adventurer){
			cards[actionCards] = i;
			actionCards++;
		  }		
		}
		
		if(actionCards > 0){
			handPos = cards[rand() % actionCards]; //select random action card
			printf("\tPlaying card: %s\n", cardName(game->hand[player][handPos]) );
			setChoice(&choice1, &choice2, &choice3, game->hand[player][handPos], game, player);
			
			//play card print error message if needed
			if(playCard(handPos, choice1, choice2, choice3, game) == -1){
				actions = 0;
				printf("\t----FAILED playCard----- %s\n", cardName(game->hand[player][handPos]));
				failCount++;
			}
			else{
				actions = game->numActions;
			}
		}//end if actionCards	
		else{
			actions = 0;
		}
	}//end while actions
	//printf("action cards availble = %i\n", actionCards);
	return 0;
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//MainMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
int main (int argc, char** argv) {
	struct gameState game;
	int numPlayers;
	int maxPlayers = 3;
	int minPlayers = 2;
	int i, j, loops=5;
	int seed = 1000;
	int player = 0;
	int count = 0;
	int round = 1;
	int card;	
	int cardsToGain = 3;
	int numberKingCard = 10;
	int kingSet[numberKingCard];
	int winner[MAX_PLAYERS];

	//seed random from command line or if not specified seed uing time
	if(argc > 1){
		printf("Random Seed = %i\n", atoi (argv[1]));
		srand(atoi (argv[1]));
	}
	else{
		srand(time(NULL));
	}

	//Loop for each game to be played
	for(i=0; i<loops; i++){
		
		numPlayers = (rand() % maxPlayers) +minPlayers; //set number of players 2-4
		pickCards(kingSet, numberKingCard); //pick random set of cards
		
		printf("Loop: %i\n", i);
		memset(&game, 23, sizeof(struct gameState));   // clear the game state
		if(initializeGame(numPlayers, kingSet, seed, &game) == -1){ // initialize a new game
			printf("GAME INITILIAZATION FAILED:\n");
			failCount++;
		}
		
		for(j=0; j<cardsToGain; j++){
			card = kingSet[rand()%numberKingCard];
			game.hand[player][i] = card;
			//gainCard(int supplyPos, struct gameState *state, int toFlag, int player)
			//gainCard(card, &game, 0, player);
			//================================================================================================
		}
		shuffle(player, &game);
		
		printf("numPlayers: %i\n", numPlayers);
		//for(j=0; j<numberKingCard; j++){
		//	printf("\tKingCard[%i] = %s\n", j, cardName(kingSet[j]));	
		//}
		
		printf("**********Loop %i *************************\n", i);
		actionPhase(&game);
		
		
		
	}//end main game for loop
		
	printf("\n\nEND TESTGAMEPLAY.C\n\n");
	//fclose(fd);
	if(failCount == 0){
		printf("TESTGAMEPLAY.C ALL TESTS PASSED\n");
	}
	return 0;
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM